package cc.magicjson.scenario.implement.module.jdbc.template.util;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;

/**
 * 异常工具类
 */
public class ExceptionUtils {

    private ExceptionUtils() {
        throw new IllegalStateException("Utility class");
    }

    /**
     * 获取完整的异常堆栈信息
     */
    public static String getStackTrace(Throwable throwable) {
        if (throwable == null) {
            return "";
        }

        try (StringWriter sw = new StringWriter();
             PrintWriter pw = new PrintWriter(sw)) {
            throwable.printStackTrace(pw);
            return sw.toString();
        } catch (IOException e) {
            return throwable.getMessage();
        }
    }

    /**
     * 获取根本原因异常
     */
    public static Throwable getRootCause(Throwable throwable) {
        if (throwable == null) {
            return null;
        }

        Throwable cause = throwable.getCause();
        if (cause == null) {
            return throwable;
        }

        Throwable rootCause = cause;
        while (rootCause.getCause() != null) {
            rootCause = rootCause.getCause();
        }
        return rootCause;
    }

    /**
     * 获取异常简短描述
     */
    public static String getErrorSummary(Throwable throwable) {
        if (throwable == null) {
            return "";
        }

        return String.format("%s: %s",
            throwable.getClass().getSimpleName(),
            throwable.getMessage());
    }

    /**
     * 获取指定深度的堆栈信息
     */
    public static String getStackTrace(Throwable throwable, int depth) {
        if (throwable == null) {
            return "";
        }

        StackTraceElement[] stackTrace = throwable.getStackTrace();
        StringBuilder sb = new StringBuilder();
        sb.append(throwable).append("\n");

        int printDepth = Math.min(depth, stackTrace.length);
        for (int i = 0; i < printDepth; i++) {
            sb.append("\tat ").append(stackTrace[i]).append("\n");
        }

        return sb.toString();
    }
}
